<template>
  <div class="flex justify-center pb-2">
    <div class="w-full max-w-md" :style="{ width: `${bgWidth}px` }" v-loading="isVerifying">
      <!-- 背景图容器 -->
      <div class="relative border border-gray-200 rounded-xl overflow-hidden shadow-sm"
        :style="{ width: `${bgWidth}px`, height: `${bgHeight}px` }">
        <img :src="backgroundImage" class="block object-cover rounded-lg"
          :style="{ width: `${bgWidth}px`, height: `${bgHeight}px` }" alt="">
        <!-- 滑块 -->
        <div class="absolute cursor-grab rounded overflow-hidden z-10 box-border shadow-[0px_1px_14px_0px_rgba(0,0,0,0.8)] border border-white" :style="{
          width: `${sliderWidth}px`,
          height: `${sliderHeight}px`,
          left: `${sliderLeft}px`,
          top: `${sliderTop}px`,
          display: isDragging || isSuccess ? 'block' : 'none'
        }">
          <img v-if="sliderImage" :src="sliderImage" :style="{ width: `${sliderWidth}px`, height: `${sliderHeight}px` }"
            alt="验证码滑块">
          <span v-else >暂无图片</span>
        </div>
      </div>

      <!-- 拖动条 -->
      <div class="relative h-8 mt-2 bg-[#F3F3F3] rounded-[8px] select-none" :style="{ width: `${bgWidth}px` }">
        <div class="absolute h-full bg-[#007AFF] rounded-[8px] transition-all duration-100 ease-in-out"
          :style="{ width: `${trackWidth}px` }"></div>
        <div
          class="absolute top-0 w-9 h-8 bg-[#CCE1F6] border border-gray-200 rounded-[8px] shadow-sm flex items-center justify-center cursor-pointer z-30 transition-colors duration-200 hover:bg-blue-50"
          :style="{ left: `${sliderLeft}px` }" @mousedown="startDrag" @touchstart="startDrag">
          <ChevronsRight class="size-5" color="#007AFF" />
        </div>
        <div class="absolute w-full h-full leading-8 text-center text-[12px] text-gray-500 z-10">
          按住左边按钮滑动完成上方拼图
        </div>
      </div>

      <!-- 刷新按钮 -->
      <div class="flex justify-between items-center mt-3">
        <el-button type="primary" link :icon="RotateCw" @click="refreshCaptcha" :disabled="isVerifying">刷新</el-button>
        <div class="flex items-center">
          <el-icon v-if="isSuccess">
            <CircleCheck class="text-[#007AFF]" size="16" />
          </el-icon>
          <span class="text-[12px] text-gray-500 ml-2">{{ statusText }}</span>
        </div>

      </div>
    </div>
  </div>
</template>

<script setup>
import { getSliderCaptchaApi, verifySliderCaptchaApi } from '#/api/system/systemOrg';
import { ref, onMounted, onUnmounted } from 'vue';
import { RotateCw, ChevronsRight, Check, CircleCheck } from '@vben/icons';
import { debounceFn } from "#/utils/debounce";

// 组件参数
const props = defineProps({
  bgWidth: { type: Number, default: 264 },
  bgHeight: { type: Number, default: 148 },
  sliderWidth: { type: Number, default: 48 },
  sliderHeight: { type: Number, default: 48 },
  phone: { type: String, default: '' }
});

// 组件事件
const emit = defineEmits(['verifySuccess', 'verifyFail']);

// 状态变量
const backgroundImage = ref('');
const sliderImage = ref('');
const captchaId = ref('');
const sliderLeft = ref(0);
const sliderTop = ref(0);
const trackWidth = ref(0);
const isDragging = ref(false);
const isSuccess = ref(false);
const statusText = ref('');
const startX = ref(0);
const initialLeft = ref(0);
const isVerifying = ref(false);

// 生成验证码
const generateCaptcha = async () => {
  try {
    isVerifying.value = true;
    const data = await getSliderCaptchaApi();
    backgroundImage.value = data.backgroundImage;
    sliderImage.value = data.sliderImage;
    captchaId.value = data.id;

    // 随机生成滑块Y轴位置
    sliderTop.value = data.sliderY
    resetState();
  } catch (error) {
    console.error('生成验证码失败:', error);
    statusText.value = '生成失败，请刷新';
  } finally {
    isVerifying.value = false;
  }
};

// 刷新验证码
const refreshCaptcha = () => {
  // resetState();
  generateCaptcha();
};

// 重置状态
const resetState = () => {
  sliderLeft.value = 0;
  trackWidth.value = 0;
  isDragging.value = false;
  isSuccess.value = false;
  statusText.value = '';
};

// 开始拖动
const startDrag = debounceFn((e) => {
  if (isVerifying.value || isSuccess.value) return;

  isDragging.value = true;
  startX.value = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
  initialLeft.value = sliderLeft.value;

  // 添加事件监听
  document.addEventListener('mousemove', handleDrag);
  document.addEventListener('mouseup', stopDrag);
  document.addEventListener('touchmove', handleDrag);
  document.addEventListener('touchend', stopDrag);
}, 200);

// 拖动中
const handleDrag = (e) => {
  if (!isDragging.value) return;

  const clientX = e.type.includes('mouse') ? e.clientX : e.touches[0].clientX;
  let diffX = clientX - startX.value;
  let newLeft = initialLeft.value + diffX;

  // 限制拖动范围
  if (newLeft < 0) newLeft = 0;
  else if (newLeft > props.bgWidth - props.sliderWidth) {
    newLeft = props.bgWidth - props.sliderWidth;
  }

  sliderLeft.value = newLeft;
  trackWidth.value = newLeft + props.sliderWidth / 2;
};

// 结束拖动
const stopDrag = async () => {
  if (!isDragging.value) return;

  isDragging.value = false;
  // isVerifying.value = true;
  statusText.value = '验证中...';

  // 移除事件监听
  document.removeEventListener('mousemove', handleDrag);
  document.removeEventListener('mouseup', stopDrag);
  document.removeEventListener('touchmove', handleDrag);
  document.removeEventListener('touchend', stopDrag);

  // 验证滑块位置
  try {
    const data = await verifySliderCaptchaApi({
      id: captchaId.value,
      sliderX: Math.round(sliderLeft.value),
      param: props.phone
    })
    if (data) {
      isSuccess.value = true;
      statusText.value = '验证成功';
      // 验证成功后保持滑块在当前位置
      emit('verifySuccess', data);
    } else {
      statusText.value = data.message;
      sliderLeft.value = 0;
      trackWidth.value = 0;
      emit('verifyFail');
    }
  } catch (error) {
    console.error('验证失败:', error);
    sliderLeft.value = 0;
    trackWidth.value = 0;
    emit('verifyFail');
  } finally {
    // isVerifying.value = false;
    // statusText.value = '';
  }
};

// 组件挂载时生成验证码
// onMounted(() => {
//   generateCaptcha();
// });

// 组件卸载时移除事件监听
onUnmounted(() => {
  document.removeEventListener('mousemove', handleDrag);
  document.removeEventListener('mouseup', stopDrag);
  document.removeEventListener('touchmove', handleDrag);
  document.removeEventListener('touchend', stopDrag);
});

// 暴露刷新方法
defineExpose({ refresh: generateCaptcha, reset: resetState });
</script>
